
import java.math.BigDecimal;
import java.math.MathContext;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.util.TimerTask;
import java.util.concurrent.TimeUnit;
import java.awt.*;
import java.awt.TrayIcon.MessageType;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.font.LineMetrics;
import java.awt.geom.Rectangle2D;
import java.awt.image.RenderedImage;

import javax.imageio.ImageIO;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.SwingUtilities;

import java.io.File;
import java.io.IOException;
import java.net.URL;

import com.rsbuddy.event.events.MessageEvent;
import com.rsbuddy.event.listeners.MessageListener;
import com.rsbuddy.event.listeners.PaintListener;
import com.rsbuddy.script.ActiveScript;
import com.rsbuddy.script.Manifest;
import com.rsbuddy.script.methods.Bank;
import com.rsbuddy.script.methods.Calculations;
import com.rsbuddy.script.methods.Camera;
import com.rsbuddy.script.methods.Environment;
import com.rsbuddy.script.methods.Game;
import com.rsbuddy.script.methods.GrandExchange;
import com.rsbuddy.script.methods.Inventory;
import com.rsbuddy.script.methods.Keyboard;
import com.rsbuddy.script.methods.Menu;
import com.rsbuddy.script.methods.Mouse;
import com.rsbuddy.script.methods.Npcs;
import com.rsbuddy.script.methods.Objects;
import com.rsbuddy.script.methods.Players;
import com.rsbuddy.script.methods.Walking;
import com.rsbuddy.script.methods.Widgets;
import com.rsbuddy.script.util.Random;
import com.rsbuddy.script.util.Timer;
import com.rsbuddy.script.wrappers.Area;
import com.rsbuddy.script.wrappers.Component;
import com.rsbuddy.script.wrappers.GameObject;
import com.rsbuddy.script.wrappers.Item;
import com.rsbuddy.script.wrappers.Model;
import com.rsbuddy.script.wrappers.Npc;
import com.rsbuddy.script.wrappers.Tile;
import com.rsbuddy.script.wrappers.TilePath;
import com.rsbuddy.script.wrappers.Widget;


@Manifest(name = "Dyer", description = "This is coming together", authors = "NeN", version=1.02)
public class Dyer extends ActiveScript implements MessageListener, PaintListener, MouseListener, MouseMotionListener {
	
	// I will organise correctly
	//Other
	Thread antibanThread;
	Thread paintThread;
	Thread checkStop;

	java.util.Timer UIUpdate = new java.util.Timer();
	GrandExchange.Item DYE;
	GrandExchange.Item ingredient;
	String isAntiban = "";
	int abCount = 0;
	boolean readyToStart = false;
	String startDYE_y  = "Calculating Profit",startDYE_r  = "Calculating Profit",startDYE_b = "Calculating Profit";
    Rectangle r;
    int rX;
    Rectangle y;
    int yX;
    Rectangle b;
    int bX;
    boolean imagesInitialized = false;
    
    //Timers
	Timer timeRunning;
	long[] lapTime = {0, -1}; //first number is state if 0 then its timing.
	long startTimeMS = -1;
	long endTimeMS;
	int lapCase = 0;
    
    //UI
    dyer_UI GUI;
	
	//Integers
	int moneyID = 995, onionID = 1957, redberryID = 1951, woadID = 1793;
	int req_MONEY = 1, req_ONIONS = 2, req_DYE = 0;
	int AGGIE = 922, BANKBOOTH = 2213;
	int DYEcount = 0, tempCount = 0;
	int yellowDYE = 1765, redDYE = 1763, blueDYE = 1767;
	int required = 2;
	int startDYE = -1;
	int startingState = 0;
	int shouldStop = 0;
	
	//Components
	Component bank_MONEY, bank_ING;
	//Points
	Point bank_MONEY_p;
	Point bank_ING_p;
	
	//Areas
	Area shop = new Area(new Tile(3083, 3256), new Tile(3088, 3261));
	Area bankArea = new Area(new Tile(3088, 3240), new Tile(3097, 3247));
	
	//Paths
	Tile[] AggieTiles = {new Tile(3093, 3245), new Tile(3099, 3251), 
									new Tile(3101, 3263), new Tile(3093, 3263), 
									new Tile(3089, 3259), new Tile(3087, 3258), 
									shop.getCentralTile()};
	TilePath toAggie = Walking.newTilePath(AggieTiles);
	TilePath toBank = Walking.newTilePath(AggieTiles).reverse();
	Tile toUse_AGG;
	

	
	private enum STATES {
		BANK, WALK_TOAGGIE, WALK_TOBANK, DYE, NOTHING, NULL, KILL
	}
	
	
	public boolean isEnterAmount() {
		Mouse.move(new Point(266 + Random.nextInt(-5, 5),230  + Random.nextInt(-5, 5)));
		return Menu.getIndex("Cancel") == 0 ? true : false;
	}
	
	public boolean withdraw(final int itemID, final int count) {
		final int[] INTERFACE_BANK_TAB = { 63, 61, 59, 57, 55, 53,
			51, 49, 47 };
		if (Bank.isOpen()) {
			if (count < 0)
				throw new IllegalArgumentException("count (" + count + ") < 0");
			Item rsi = Bank.getItem(itemID);
			if (rsi == null)
				return false;
			Component item = rsi.getComponent();

			if (item == null)
				return false;
			
			//Check tab
			while(item.getRelLocation().x == 0 && Bank.getCurrentTab() != 0) {
				Widgets.getComponent(Bank.WIDGET, INTERFACE_BANK_TAB[0]).click();
				sleep(Random.nextInt(800, 1300));
			}
			
			int invCount = Inventory.getCount(true);
			switch (count) {
			case 0:
				item.interact("Withdraw-All");
				break;
			case 1:
				item.click(true);
				break;
			case 5:
			case 10:
				item.interact("Withdraw-" + count);
				break;
			default:
				if (!item.interact("Withdraw-" + count)) {
					if (item.interact("Withdraw-X")) {
						sleep(Random.nextInt(1000, 1300));
						Mouse.moveOffScreen();
						if(!Menu.isOpen()) {
						Keyboard.sendText(String.valueOf(count), true);
						} else {
							Menu.click("Withdraw-X");
						}
					}
				}
			}
			sleep(Random.nextInt(1000, 1300));
			if(rsi.getId() == moneyID) {
				bank_MONEY = item;
				bank_MONEY_p = new Point((int)item.getContentRect().getCenterX(), (int)item.getContentRect().getCenterY());
				log("Point Recorded for: " + bank_MONEY.getItemName() + "(" + bank_MONEY_p.x + "," + bank_MONEY_p.y + ")");
			}
			if(rsi.getId() == ingredient.getID()) {
				bank_ING = item;
				bank_ING_p = new Point((int)item.getContentRect().getCenterX(), (int)item.getContentRect().getCenterY());
				log("Point Recorded for: " + bank_ING.getItemName() + "(" + bank_ING_p.x + "," + bank_ING_p.y + ")");
			}
			int newInvCount = Inventory.getCount(true);
			return newInvCount > invCount || newInvCount == 28;
		}
		return false;
	}
	
	public boolean doAct(Npc np, String action) {
        for (int i = 0; i < 50; i++) {
        	if(!np.isOnScreen()) {
        		Camera.turnTo(np);
        	}
            Point click = null;
            Model m = np.getModel();
            click = getRandomPoint(m);
            
            Mouse.move(click);
            String[] menuItems = Menu.getItems();
            if(menuItems.length > 0 && menuItems[0].toLowerCase().startsWith(action.toLowerCase())) {
                Mouse.click(true);
                return true;
            } else {
             String[] items = Menu.getItems();
				for (int a = 0; a < items.length; a++) {
					if (items[a].toLowerCase().startsWith(action.toLowerCase())) {
						Mouse.click(false);
						return Menu.click(items[a]);
					}
					
				}
            }
           
        }
        return false;
    }
	
	public boolean doAct(GameObject np, String action) {
        for (int i = 0; i < 50; i++) {
        	if(!np.isOnScreen()) {
        		Camera.turnTo(np);
        	}
            Point click = null;
            Model m = np.getModel();
            click = getRandomPoint(m);
            
            Mouse.move(click);
            String[] menuItems = Menu.getItems();
            if(menuItems.length > 0 && menuItems[0].toLowerCase().startsWith(action.toLowerCase())) {
                Mouse.click(true);
                return true;
            } else {
             String[] items = Menu.getItems();
				for (int a = 0; a < items.length; a++) {
					if (items[a].toLowerCase().startsWith(action.toLowerCase())) {
						Mouse.click(false);
						return Menu.click(items[a]);
					}
					
				}
            }
           
        }
        return false;
    }
    
        public Point getRandomPoint(Model m) { //this is Enfilade's
        Polygon[] triangles = m.getTriangles();
        if(triangles.length == 0)
            return null;
        Polygon p = triangles[Random.nextInt(0, triangles.length)];
        double a = Math.random();
        double b = Math.random();
        if(a + b >= 1) {
            a = 1 - a;
            b = 1 - b;
        }
        double c = 1 - a - b;
        return new Point(
                (int)(a*p.xpoints[0] + b*p.xpoints[1] + c*p.xpoints[2]),
                (int)(a*p.ypoints[0] + b*p.ypoints[1] + c*p.ypoints[2]));
    }
	
	
	private STATES getState() {
		if(!sliderIsLeft) {
			if(GUI.shouldKill == true) {
				return STATES.KILL;
			}
		}
		if(readyToStart) {

			if(shouldStop == -1) {
				return STATES.KILL;
			}
		Npc aggie = Npcs.getNearest(AGGIE);
		Area doNot_top = new Area(new Tile(3079, 3262), new Tile(3089, 3269));
		Area doNot_mid = new Area(new Tile(3078, 3251), new Tile(3082, 3262));
		Area doNot_btm = new Area(new Tile(3078, 3251), new Tile(3086, 3255));
		
		if(!Players.getLocal().isMoving()) {
		if(doNot_top.contains(Players.getLocal().getLocation()) || doNot_mid.contains(Players.getLocal().getLocation()) || doNot_btm.contains(Players.getLocal().getLocation())) {			
			Walking.stepTowards(new Tile(3092, 3259).randomize(4,4));	
		}
		} else {
		if(doNot_top.contains(Walking.getDestination()) || doNot_mid.contains(Walking.getDestination()) || doNot_btm.contains(Walking.getDestination())) {
			Walking.stepTowards(new Tile(3092, 3259).randomize(4,4));
		}
		}
		
		if(Inventory.contains(moneyID) && Inventory.getCount(ingredient.getID()) >= (DYE.getID() == redDYE ? 3 : 2) && Inventory.getCount(ingredient.getID()) > 1 && aggie.isOnScreen()) {	
			return STATES.DYE;
		} 
		if(Inventory.contains(moneyID) && Inventory.getCount(ingredient.getID()) >= (DYE.getID() == redDYE ? 3 : 2) && (aggie == null || !aggie.isOnScreen())) {
			
			return STATES.WALK_TOAGGIE;
		} 
		GameObject bank = Objects.getNearest(BANKBOOTH);
		if(Inventory.contains(moneyID) && Inventory.getCount(ingredient.getID()) <= (DYE.getID() == redDYE ? 2 : 1) && bank.isOnScreen()) {
			return STATES.BANK;
		} 
		if(Inventory.contains(moneyID) && Inventory.getCount(ingredient.getID()) <= (DYE.getID() == redDYE ? 2 : 1) && !bank.isOnScreen()) {
		
			return STATES.WALK_TOBANK;
		} 
		if(!Inventory.contains(moneyID) && !bank.isOnScreen()) {
			return STATES.WALK_TOBANK;
		}
		if(!Inventory.contains(moneyID) && bank.isOnScreen()) {
			return STATES.BANK;
		} 
		if(!Inventory.contains(moneyID) && !bank.isOnScreen()) {
			return STATES.WALK_TOBANK;
		}
		if(!Inventory.contains(moneyID) && bank.isOnScreen()) {
			return STATES.BANK;
		} 
		return STATES.NULL;
		}
		return STATES.NULL;
	}
	
	public boolean doorIsVisible() {
		 GameObject doore = Objects.getTopAt(new Tile(3088,3258));
		 if(doore == null) {
			 return false;
		 }
		 if(doore.isOnScreen() && doore.getId() == 1530) {
			 return true;
		 }
		return false;
	}
	
	public boolean openDoor() {
		 GameObject doore = Objects.getTopAt(new Tile(3088,3258));
			if(doore != null) {
				if(doore.isOnScreen()) {
					if(!Players.getLocal().isMoving()) {
					doore.interact("Open");
					int fail = 0;
					while(doore.isOnScreen()) {
						if(fail == 6) {
							break;
						}
						sleep(250);
						if(!Players.getLocal().isMoving()) {
						fail++;
						}
					}
						return doore == null;
					}
				}
			}
			return false;
	}
	
	public void openBank() {
		GameObject banker;
		//if(Random.nextInt(0, 3) != 2) {
		banker = Objects.getTopAt(new Tile(3091, 3245));
		
		if(banker == null) {
			banker = Objects.getNearest(BANKBOOTH);
		}
		//}
			//banker.interact("Use-quickly");
			doAct(banker, "use-quickly");
			if(!Bank.isOpen()) {
				int failBitchProof = 0;
				while(!Bank.isOpen()) {
					if(failBitchProof >= 12) {
						break;
					}
				sleep(250);
				failBitchProof++;
				}
				if(!Bank.isOpen()) {
				openBank();
				}
			}
	}
	
	public int required(int what) {
		try {
		if(what == req_MONEY) {
			if(Bank.isOpen()) {
				int bank = ((Bank.getCount(ingredient.getID()) / required) * 5);
				int inv = (Inventory.getCount(ingredient.getID()) / required) * 5;
				return bank + inv;
			}
		}
		if(what == req_ONIONS) {
			if(Bank.isOpen()) {
				if(DYE.getID() != redDYE) {
				int bank = (Bank.getCount(ingredient.getID()));
				int inv = Inventory.getCount(ingredient.getID());
				return bank >= 26 ? 26 - inv : bank - inv;
				} else if(DYE.getID() == redDYE) {
					int bank = (Bank.getCount(ingredient.getID()));
					int inv = Inventory.getCount(ingredient.getID());
					return bank >= 27 ? 27 - inv : bank - inv;	
				}
			}
		}
		if(what == req_DYE) {
			if(Bank.isOpen()) {
				int bank = (Bank.getCount(DYE.getID()));
				int inv = Inventory.getCount(DYE.getID());
				int bank2 = ((Bank.getCount(ingredient.getID()) / required));
				int inv2 = (Inventory.getCount(ingredient.getID()) / required);
				if(bank == -1 && inv == -1 && bank2 == -1 && inv2 == -1) {
					return required(req_DYE);
				}
				return bank + inv + bank2 + inv2;

		}
		}
		} catch (Exception e) {
			required(what);
		}
		return -1;
	}
	
	public boolean selectOnion(Item onion) throws InterruptedException {
		if(Inventory.contains(onion.getId())) {

			if(!Inventory.isItemSelected()) {

			//if(!Inventory.getSelectedItem().isComponentValid()) {
			if(onion.interact("Use")) {
				sleep(100);
				if(Inventory.getSelectedItem().getId() == onion.getId()) {
					return true;				
				}
				sleep(300);
				selectOnion(onion);
			}
			} else {
				if(Inventory.getSelectedItem().getId() == onion.getId()) {
					return true;				
				}
				Inventory.getSelectedItem().click(true);
				return false;
			}
			//} else {
			//	if(Inventory.getSelectedItem().getId() != onion.getId()) {
			//		return true;
			//	}
			//}
		}
		return false;
	}
	
	private Tile randomize(Tile t, int N, int S, int E, int W) {
		int x = t.getX() - S;
		x = x + N;
		int y = t.getY() + E;
		y = y - W;
		return new Tile(x,y);
		
	}

	
	@Override
	public boolean onStart() {
		timeRunning = new Timer(0);
		Mouse.setSpeed(Random.nextInt(5,8));
		paintThread = new Thread(new paintingThread());
		paintThread.start();
		
		new Thread(new Runnable() {

			@Override
			public void run() {
				// TODO Auto-generated method stub
				logo = getImage("logo", "http://i.imgur.com/CR8L6.png");
				img1 = getImage("chooseBG", "http://imgur.com/Ezva7.png");
			    img2 = getImage("red", "http://services.runescape.com/m=itemdb_rs/3338_obj_big.gif?id=1763");
			    img3 = getImage("yellow", "http://services.runescape.com/m=itemdb_rs/3338_obj_big.gif?id=1765");
			    img4 = getImage("blue", "http://services.runescape.com/m=itemdb_rs/3338_obj_big.gif?id=1767");
			    img1_over = getImage("hover", "http://i.imgur.com/969Mc.png");
			    confirm = getImage("confirm", "http://i.imgur.com/QWXro.png");
			    // bg = getImage("bg", "http://i.imgur.com/DaVUd.png");
			    sliderBG = getImage("sliderBG", "http://i.imgur.com/07hlp.png");
			    sliderBG_l = getImage("sliderBG_l", "http://i.imgur.com/4E7PG.png");
			    sliderBG_r = getImage("sliderBG_r", "http://i.imgur.com/m9nUEl.png");
			    slider = getImage("slider","http://i.imgur.com/ZrIi9.png");

				places = new Rectangle[]{new Rectangle(20, 73, img1.getWidth(null), img1.getHeight(null)), //red
									  new Rectangle(184, 73, img1.getWidth(null), img1.getHeight(null)), //yellow
									  new Rectangle(343, 73, img1.getWidth(null), img1.getHeight(null))}; //blue
				
				confirmRec = new Rectangle(145, 360, confirm.getWidth(null), confirm.getHeight(null));
				sliderRec_l = new Rectangle(207,278, slider.getWidth(null), slider.getHeight(null));
				sliderRec_r = new Rectangle(237,278, slider.getWidth(null), slider.getHeight(null));
				imagesInitialized = true;
			}
			
		}).start();
		return true;
	}
	
	@Override
	public void onFinish() {
		antibanThread = null;
		paintThread = null;
		checkStop = null;
		if(!sliderIsLeft) {
			UIUpdate.cancel();
			SystemTray.getSystemTray().remove(GUI.tray);
			GUI.dispose();
			GUI = null;
		}
	}
	
	public String setLapTimer() {
		try {
		if(lapTime[0] == 1) {
			long time = System.currentTimeMillis() - startTimeMS;
			long cocks = TimeUnit.MILLISECONDS.toSeconds(time) - 
		    TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(time));
			return String.format(cocks <= 9 ? "%d:0%d" : "%d:%d", 
				    TimeUnit.MILLISECONDS.toMinutes(time),
				    cocks
				); 
		} else if(lapTime[0] == 2) {
			if(lapCase == 2) {
			if(lapTime[1] == -1) {
			long time = endTimeMS - startTimeMS;
			lapTime[1] = time;
			}
			long cocks = TimeUnit.MILLISECONDS.toSeconds(lapTime[1]) - 
		    TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(lapTime[1]));
			return String.format(cocks <= 9 ? "%d:0%d" : "%d:%d", 
				    TimeUnit.MILLISECONDS.toMinutes(lapTime[1]),
				    cocks
				);
			}
			
		}
		return " ";
		} catch (Exception e) {
			e.printStackTrace();
			return "";
		}
	}

	@Override
	public int loop() {
		try {
			while(!readyToStart) {
			
				sleep(500);
			}
			if(antibanThread == null) {
				antibanThread = new Thread(new antiBan());
				antibanThread.start();
			}
		switch(getState()) {
		
					case KILL:
					return -1;
					
				case BANK:
					if(!Bank.isOpen()) {
						openBank();
					}
					
	

					//starting shit
					 if(startDYE == -1) {
						new Thread(new Runnable() {

							@Override
							public void run() {
								// TODO Auto-generated method stub
								startDYE = required(req_DYE);
							}
							
						}).start();
					} 
					//end start

					int safe = 0;
					if(Inventory.contains(DYE.getID())) {
					Bank.deposit(DYE.getID(), 0);
					while(Inventory.contains(DYE.getID())) {
						if(safe == 10) {
							return 100;
						}
						sleep(300);
						safe++;

						if(Inventory.contains(ingredient.getID())) {
							Bank.deposit(ingredient.getID(), 0);
						}
					}
					if(lapCase == 1) {
						endTimeMS = System.currentTimeMillis();
						lapTime[0] = 2; //the timer is set
						lapCase = 2;
					}
					DYEcount = Bank.getCount(DYE.getID());
					}
	
					//END CHECK
						if(!Inventory.contains(moneyID) || Inventory.getItem(moneyID).getStackSize() >= (required == 3 ? 9 * 5 : 13 * 5)) {					
							while(!Inventory.contains(moneyID)) {
								if(!Bank.isOpen())
									break;
								if(bank_MONEY != null) {
									if(isStop() == -1) {
										return -1;
									}
									int x = bank_MONEY_p.x + Random.nextInt(-3, 3);
									int y = bank_MONEY_p.y + Random.nextInt(-3, 3);
									int count = required(req_MONEY);
									Point item = new Point(x,y);
									Mouse.move(item);
									if(bank_MONEY.getContentRect().contains(Mouse.getLocation())) {
										Mouse.click(false);
										if (!Menu.contains("Withdraw-" + count + " " + bank_MONEY.getItemName().substring(13, bank_MONEY.getItemName().length()))) {
											if (Menu.contains("Withdraw-X")) {
												if(Menu.click("Withdraw-X " + bank_MONEY.getItemName().substring(13, bank_MONEY.getItemName().length()))) {
												sleep(Random.nextInt(1000, 1300));
												if(!Inventory.contains(moneyID)) {
												Keyboard.sendText(String.valueOf(count), true);
												}
												}
											}
										} else {
											Menu.click("Withdraw-" + count);
										}
										sleep(Random.nextInt(250, 750));
									}
								} else  {
									Bank.withdraw(moneyID, required(req_MONEY));
									bank_ING = Bank.getItem(ingredient.getID()).getComponent();
									bank_ING_p = new Point(bank_ING.getCenter().x, bank_ING.getCenter().y);	
								}

								sleep(Random.nextInt(250, 750));
							}
						}
						
						while(Inventory.getCount(ingredient.getID()) <= (required == 3 ? 2 : 1)) {
	
							if(bank_ING != null) {
								int x = bank_ING_p.x + Random.nextInt(-3, 3);
								int y = bank_ING_p.y + Random.nextInt(-3, 3);
								int count = required(req_ONIONS);
								Point item = new Point(x,y);
								Mouse.move(item);
								if(bank_ING.getContentRect().contains(Mouse.getLocation())) {
									Mouse.click(false);
									if (!Menu.contains("Withdraw-" + count + " " + bank_ING.getItemName().substring(13, bank_ING.getItemName().length()))) {
										if (Menu.contains("Withdraw-X")) {
											if(Menu.click("Withdraw-X " + bank_ING.getItemName().substring(12, bank_ING.getItemName().length()))) {
											
											if(Inventory.getCount(ingredient.getID()) < (DYE.getID() == redDYE ? 3 : 2)) {
												sleep(Random.nextInt(1000, 1300));
											Keyboard.sendText(String.valueOf(count), true);
											}
										}
										}
									} else {
										Menu.click("Withdraw-" + count);
									}
									sleep(Random.nextInt(250, 750));
								}
							} else if(bank_ING == null) {
								if(isStop() == -1) {
									return -1;
								}
								Bank.withdraw(ingredient.getID(), required(req_ONIONS));
								bank_ING = Bank.getItem(ingredient.getID()).getComponent();
								bank_ING_p = new Point(bank_ING.getCenter().x, bank_ING.getCenter().y);

								//Bank.withdraw(ingredient.getID(), required(req_ONIONS));	
							}
							

							
							sleep(Random.nextInt(250, 750));
						}
						
						if(lapCase == 0 && startTimeMS == -1) {
							log("Lap Time Recording Started");
							startTimeMS = System.currentTimeMillis();
							lapTime[0] = 1; //the timer is set
							endTimeMS = -1;
						}
	
					Bank.close();
					
				return 100;
				
				case DYE:
					if(lapCase == 0 && startTimeMS != -1) {
						lapCase = 1;
						log("Set Lap Case: " + lapCase);

					}
					// int itemCount = Inventory.getCount(ingredient.getID());
					Npc aggie = Npcs.getNearest(AGGIE);
					Component iface = Widgets.get(64).getComponent(5);
					//if(shop.contains(Players.getLocal().getLocation())) {
					
					if(!shop.contains(Players.getLocal().getLocation())) {
						while(doorIsVisible()) {
							openDoor();
							sleep(500);
						}
					}
					
					do {
						if((iface.click())) {
							return 100;
						}
						selectOnion(Inventory.getItem(ingredient.getID()));
						sleep(Random.nextInt(350, 850));
					} while(Inventory.getSelectedItem().getId() != ingredient.getID() && !iface.isValid() && !Players.getLocal().isMoving());
					
					
					
					do {
						doAct(aggie, "use " + ingredient.getName().toLowerCase() + " -> aggie");
						while(Players.getLocal().isMoving()) {
							sleep(250);
						}
						sleep(Random.nextInt(200, 600));
						while(iface.isValid()) {
						iface.click();
						}
						sleep(Random.nextInt(400,1000));
					} while (Inventory.getSelectedItem().getId() == ingredient.getID());
					
					sleep(200);
						
				return 100;
				
				case WALK_TOAGGIE:
					Npc agg = Npcs.getNearest(AGGIE);
					if(doorIsVisible()) {
						openDoor();
					}
					GameObject door = Objects.getTopAt(new Tile(3088,3258));
					if(!shop.contains(Players.getLocal().getLocation())) {
						if(!Players.getLocal().isMoving() || Calculations.isTileOnMap(toAggie.getNext())) {
						//toAggie.randomize(1, 1).traverse();
							if(toUse_AGG == null) {
							int NorthDev = shop.getNearestTile().getY() - shop.getCentralTile().getY();
							int EastDev = shop.getNearestTile().getX() - shop.getCentralTile().getX();
							toUse_AGG = randomize(shop.getNearestTile(), NorthDev, 0, EastDev, 0);
							}
							if(Calculations.isTileOnMap(toUse_AGG.randomize(1,1)) && door == null) {
								Walking.stepTowards(toUse_AGG.randomize(1,1));
					
								return 100;
							} else {
								if(Calculations.distanceTo(Walking.getDestination()) < 4)
							toAggie.randomize(2,2).traverse();
							}
						}
					} else {
						Camera.turnTo(agg);
					}
					return 100;
				
				case WALK_TOBANK:
					GameObject bank = Objects.getTopAt(new Tile(3091, 3245));
					if(doorIsVisible()) {
						openDoor();
					}
					if(!bank.isOnScreen() || bank == null) {
						if(!Players.getLocal().isMoving() || Calculations.isTileOnMap(toAggie.getNext())) {
						//toAggie.randomize(1, 1).traverse();
							if(Calculations.isTileOnMap(bankArea.getCentralTile().randomize(2,2))) {
								Walking.stepTowards(bankArea.getCentralTile().randomize(2,2));
								int failsafe = 0;
								while(Calculations.distanceTo(Walking.getDestination()) > 4 || !bank.isOnScreen()) {
									if(failsafe >= 8) {
										break;
									}
									if(doorIsVisible()) {
										openDoor();
									}
									sleep(250);
									failsafe++;
								}
								return 100;
							} else {
								if(Calculations.distanceTo(Walking.getDestination()) < 4)
									toBank.randomize(2,2).traverse();
							}
						}
					}
					return 100;
		
				case NOTHING:						
				return 100;
		}

		
		} catch (Exception e) {
			
		}
		return Random.nextInt(100,500);
	}


	public void messageReceived(MessageEvent m) {
		// TODO Auto-generated method stub
		
	}
	
	private int isStop() throws InterruptedException {
		for(int i = 0; i <= 3; i++) {
			if(!Inventory.contains(ingredient.getID()) || !Inventory.contains(moneyID)) {
				
				if(!Bank.isOpen()) {
				openBank();
				}
					if(Bank.isOpen()) {
					if(Bank.getCount(ingredient.getID()) <= (DYE.getID() == redDYE ? 2 : 1) || Bank.getCount(moneyID) == -1) {
						if(i == 3) {
						log("No Materials - Stopping...");
						Game.logout(false);
						return -1;
						}
					}
					}
		}
			sleep(1000);
		}
		return 100;
	}
	
	private String giveNumber(int input) {
		MathContext mc = new MathContext(4, RoundingMode.DOWN);
		BigDecimal bigDecimal = new BigDecimal(new Double(input/1000), mc);
		DecimalFormat myFormatter = new DecimalFormat("#'.'##'k'");
		return myFormatter.format(bigDecimal.intValue());
	}

    //START: Code generated using Enfilade's Easel
    private final RenderingHints antialiasing = new RenderingHints(
            RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    
    public Image getImage(String fileName, String URL){
        try {
        	if(!URL.endsWith(".gif")) {
        	fileName = fileName + ".png";
        	} else if(URL.endsWith(".gif")) {
        	fileName = fileName + ".gif";
        	}
          File f = new File(Environment.getStorageDirectory() + System.getProperty("file.separator") + "dyerNEN"  + System.getProperty("file.separator") + fileName);
          File folder = new File(Environment.getStorageDirectory() + System.getProperty("file.separator") + "dyerNEN");
          if (folder.exists()) {
              if(f.exists()) {
            return ImageIO.read(f.toURI().toURL());
              }
          }
          if(!folder.exists()) {
        	  folder.mkdirs();
          }
          f.mkdirs();
          Image img = ImageIO.read(new URL(URL));
          if (img != null) {
        	  if(fileName.contains(".gif")) {
        		  ImageIO.write((RenderedImage)img, "gif", f);
        	  } else {
        		  ImageIO.write((RenderedImage)img, "PNG", f);
        	  }
            
            log("Saved " + fileName + " to Scripts folder successfully.");
            return img;
          }
        } catch(Exception e) {
            log(e.toString());
        }
        return null;
      }


    private final Color color1 = new Color(0, 0, 0, 152);
    private final Color color2 = new Color(3, 135, 3);
    private final Color color3 = new Color(0, 0, 0, 154);
    private final Color color4 = new Color(1, 0, 0);

    private final Font font1 = new Font("Comic Sans MS", 0, 17);
    private final Font font2 = new Font("Comic Sans MS", 0, 12);
    
    public Image logo = null;
    private Image img1 = null;
    private Image img2 = null;
    private Image img3 = null;
    private Image img4 = null;
    private Image img1_over = null;
    private Image confirm = null;
    // private final Image bg = getImage("bg", "http://i.imgur.com/DaVUd.png");
    private final Image notify_bg = getImage("notify_bg", "http://nen.herobo.com/script-images/chopnburn/notify_bg.png");
    private final Image notify_left = getImage("notify_left", "http://nen.herobo.com/script-images/chopnburn/notify_left.png");
    private final Image notify_right = getImage("notify_right", "http://nen.herobo.com/script-images/chopnburn/notify_right.png");
    private Image sliderBG = null;
    private Image sliderBG_l = null;
    private Image sliderBG_r = null;
    private Image slider = null;

    
	Rectangle[] places; //blue
	
	Rectangle confirmRec;
	Rectangle sliderRec_l;
	Rectangle sliderRec_r;
	String cost, profit, total = "";
	int paintDYE = 0;
	
	boolean sliderIsLeft = true;
    
    int hoveredImg = 3;
    int clickedImg = 3;
    int confirmHov = 0;
    
    private Rectangle getStringBounds(String s, Graphics g) {
        LineMetrics l = g.getFontMetrics().getLineMetrics(s, g);
        Rectangle2D r = g.getFontMetrics().getStringBounds(s, g);
        return new Rectangle(0, (int)l.getAscent(), (int)r.getWidth(), (int)r.getHeight());
    }
    
    public int getImageCount(Rectangle bound) {
        if(bound == null)
            return -1;
        double count = (bound.getWidth() / 6);
        return (int) (Math.round(count));
    }
    
    private void drawNotify(Graphics2D g, String s) { //259, 169
        int y = 149;
        Rectangle bounds = getStringBounds(s, g);
        int length = (int) (Math.round(bounds.getWidth()));
        int height = (int) (Math.round(bounds.getHeight())) + 4;
        int images = getImageCount(bounds);
        int x = (247 - (((length)/2)));
        int width = x + 6;
        g.drawImage(notify_left, x, y, null);
        int k = 0;
        int distance = 0;
        for(k = 0; k < images; k++) {
          g.drawImage(notify_bg, width + distance, y, null);
          distance = distance + 6;
        }
       /* for(k = 0; k < length; k = k+2) {
          g.drawImage(notify_bg, width + k, y, null);
        } */
        g.drawImage(notify_right, x + (distance + 6), y, null);
        g.setColor(new Color(0,0,0,110));
        g.drawString(s, (width + 1), y + (height));
        g.setColor(Color.white);
        g.drawString(s, (width), y + (height - 1));
    }
    

    
    Graphics2D myG;

    public void onRepaint(Graphics g1) {
        Graphics2D g = (Graphics2D)g1;
        g.setRenderingHints(antialiasing);
        if(Game.isLoggedIn()) {
        	if(!imagesInitialized) {
            	drawNotify(g, "Grabbing Images...");
            }
        	if(imagesInitialized) {

        	if(!readyToStart) {
        		myG = g;
            if(startingState == 0) {
        		if(clickedImg != 3) {
        			g.drawImage(img1_over, places[clickedImg].x, places[clickedImg].y, null);
        			if(confirmHov == 1)
        				g.drawImage(confirm, 145, 360, null);
        			
        				g.drawImage(confirm, 145, 360, null);
        		} 
        	if(hoveredImg <= 2) {
        		if (clickedImg != hoveredImg) {
        			g.drawImage(img1, places[hoveredImg].x, places[hoveredImg].y, null);
        		}
        	}

        if(clickedImg != 0) {
        g.drawImage(img1, 20, 73, null);
        }
        if(clickedImg != 1) {
        g.drawImage(img1, 184, 73, null);
        }
        if(clickedImg != 2) {
        g.drawImage(img1, 343, 73, null);
        }
        
        
        g.drawImage(img2, 49, 102, null);
        g.drawImage(img3, 212, 103, null);
        g.drawImage(img4, 372, 102, null);
        g.setFont(font1);
        g.setColor(color1);
        g.drawString("Blue Dye", 386, 196);
        g.drawString("Yellow Dye", 217, 198);
        g.drawString("Red Dye", 65, 199);
        g.setColor(new Color(196,196,196));
        g.drawString("Blue Dye", 385, 195);    
        g.drawString("Yellow Dye", 216, 197);
        g.drawString("Red Dye", 64, 198);
        g.setFont(font2);
        g.setColor(color4);
        g.drawString("2 Onions", 237, 215);
        g.drawString("2 Woad Leaves", 381, 213);
        g.drawString("3 Redberries", 64, 215);
        //bounds


        
        g.drawString(startDYE_r, rX, 230);
        g.drawString(startDYE_y, yX, 230);
        g.drawString(startDYE_b, bX, 230);

        
        // slider
        if(sliderIsLeft) {
        g.drawImage(sliderBG_l, 22, 274, null);
        g.drawImage(slider, sliderRec_l.x, sliderRec_l.y, null);
        } else if(!sliderIsLeft) {
            g.drawImage(sliderBG_r, 22, 274, null);
            g.drawImage(slider, sliderRec_r.x, sliderRec_r.y, null);	
        }
  

            } else {
            	drawNotify(g, "Starting Script...");
            }

        } else if(readyToStart) {
        	 
        	 if(sliderIsLeft) {
        	 g.drawString("State: " + getState().name(), 200, 15);
        	 g.drawString("Time Running: " + timeRunning.toElapsedString(), 200, 30);
             g.drawString("Dyes: " + paintDYE + " of " + startDYE, 200, 45);
             g.drawString("Cost to make: " + cost, 200, 60);
             g.drawString("Profit : " + profit, 200, 75);
             g.drawString("Total Value: " + total, 200, 90);
        	 }
        	 /*
                g.drawImage(bg, 1, 251, null);
                g.setFont(new Font("Trebuchet MS", 0, 16));
                g.setColor(new Color(0,0,0));
                g.drawString(timeRunning.toElapsedString(), 150, 365);
                g.drawString(paintDYE + " of " + startDYE, 88, 385);
                g.drawString(cost, 87, 404);
                g.drawString(profit, 98, 423);
                g.drawString(total, 98, 443);
                g.drawString("ph", 120, 462);
          */
        }
        }
        }
    }
    //END: Code generated using Enfilade's Easel


	
	public class antiBan implements Runnable {

		@Override
		public void run() {
			// TODO Auto-generated method stub
			while(antibanThread != null) {
				
				try {
			if(Game.isLoggedIn()) {
				int id = Random.nextInt(0, 5);
				switch(id) {
					case 1:
					isAntiban = "Setting Pitch - MAXIMUM";
					Camera.setPitch(true);
					break;
					
					case 2:
						int time = Random.nextInt(0, 5000); 
						isAntiban = "Moving Camera Randomly for " + time + "ms";
					Camera.moveRandomly(time);
					break;
					
						case 3:
							isAntiban = "Setting Pitch - MINIMUM";
						Camera.setPitch(false);
						break;
						
						case 4:
							int pitch = Random.nextInt(5, 100);
							isAntiban = "Setting Pitch to " + pitch + "%";
						Camera.setPitch(pitch);
						break;
						
						default:
							isAntiban = "";
						break;
				}
				abCount++;

						Thread.sleep(Random.nextInt(5000, 60000));


			}
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
	}

	@Override
	public void mouseClicked(MouseEvent m) {
		// TODO Auto-generated method stub
		if(!readyToStart && imagesInitialized) {
		if(sliderIsLeft) {
			if (sliderRec_r.contains(m.getPoint())) {
				sliderIsLeft = false;
			}
		}
		if(!sliderIsLeft) {
			if (sliderRec_l.contains(m.getPoint())) {
				sliderIsLeft = true;
			}
		}
		if(places[0].contains(m.getPoint())) {
			clickedImg = 0;
		}
		else if(places[2].contains(m.getPoint())) {
			clickedImg = 2;
		}
		else if(places[1].contains(m.getPoint())) {
			clickedImg = 1;
		}
		
		if(confirmRec.contains(m.getPoint())) {
			if(clickedImg != 3) {

				startingState = 1;
				if(clickedImg == 0) {
					new Thread(new Runnable() {
						@Override
						public void run() {
							DYE = GrandExchange.lookup(redDYE);
							ingredient = GrandExchange.lookup(redberryID);	
						}
						
					}).start();

					required = 3;
					
				} else if(clickedImg == 1) {
					new Thread(new Runnable() {
						@Override
						public void run() {
							DYE = GrandExchange.lookup(yellowDYE);
							ingredient = GrandExchange.lookup(onionID);	
						}
						
					}).start();
				} else {
					new Thread(new Runnable() {
						@Override
						public void run() {
							DYE = GrandExchange.lookup(blueDYE);
							ingredient = GrandExchange.lookup(woadID);	
						}
						
					}).start();
				}
				readyToStart = true;
				if(!sliderIsLeft) {
					
					SwingUtilities.invokeLater(new Runnable() {

						@Override
						public void run() {
							// TODO Auto-generated method stub
							GUI = new dyer_UI();
							GUI.setVisible(true);
							UIUpdate.scheduleAtFixedRate(new TimerTask() {

								@Override
								public void run() {
									// TODO Auto-generated method stub
									GUI.timeElapsed.setText(timeRunning.toElapsedString());
								}
								
							}, 0, 1000);
						}
						
					});
					
				}
			}
		}
		}
	}

	@Override
	public void mouseEntered(MouseEvent m) {
		// TODO Auto-generated method stub


	}

	@Override
	public void mouseExited(MouseEvent arg0) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void mousePressed(MouseEvent arg0) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void mouseReleased(MouseEvent arg0) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void mouseDragged(MouseEvent arg0) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void mouseMoved(MouseEvent m) {
		// TODO Auto-generated method stub

		if(!readyToStart && imagesInitialized) {
		if(places[0].contains(m.getPoint())) {
			hoveredImg = 0;
		}
		else if(places[2].contains(m.getPoint())) {
			hoveredImg = 2;
		}
		else if(places[1].contains(m.getPoint())) {
			hoveredImg = 1;
		}
		else if(confirmRec.contains(m.getPoint())) {
			confirmHov = 1;
		} 
		else {
			hoveredImg = 3;	
			confirmHov = 0;
		}
		}
		

	}
	
	public class paintingThread implements Runnable {
		
		@Override
		public void run() {
			// TODO Auto-generated method stub
			while(paintThread != null) {
				try {
					if(readyToStart) {
						
						if(sliderIsLeft) {
							tempCount = Inventory.getCount(DYE.getID());
					       	 paintDYE = DYEcount + tempCount;
					    	 cost = "" + (((paintDYE * required) * ingredient.getGuidePrice()) + (paintDYE * 5));
					    	 int totalI = paintDYE * DYE.getGuidePrice();
					    	 int costI = (paintDYE * required) * ingredient.getGuidePrice();
					    	 profit = "" + (int)(totalI - costI);
					    	 total = "" + totalI;
					    	 Thread.sleep(Random.nextInt(1000,3000));
						} else if(!sliderIsLeft) {
							tempCount = Inventory.getCount(DYE.getID());
					       	 paintDYE = DYEcount + tempCount;
					    	 cost = "" + (((paintDYE * required) * ingredient.getGuidePrice()) + (paintDYE * 5));
					    	 int totalI = paintDYE * DYE.getGuidePrice();
					    	 int costI = (paintDYE * required) * ingredient.getGuidePrice();
					    	 profit = "" + (int)(totalI - costI);
					    	 total = "" + totalI;
					    	 
					    	 // ere
					    	 
					         GUI.dyesMade.setText(paintDYE + " of " + startDYE);
				             GUI.costToMake.setText(cost);
				             GUI.profit.setText(profit);
				             GUI.totalGained.setText(total);					    	 
					    	 //input ERE
							GUI.state.setText("" + getState().toString());
							GUI.timeElapsed.setText(timeRunning.toElapsedString());
							GUI.lapTime.setText(setLapTimer());
							GUI.repaint();
							String prior = GUI.updateIntervals_txt.getText();
							int type =  GUI.updateIntervals_cmb.getSelectedIndex();
							if(type == 0) { //millis
								int updateInt = Integer.valueOf(prior);
								Thread.sleep(updateInt);
							} else if(type == 1) { //seconds
								Double updateInt = Double.valueOf(prior);
								int update = (int)(updateInt * 1000);
								Thread.sleep(update);
							} else if(type == 2) { //minutes
								
							}
						}
						
					} else {
						if(Game.isLoggedIn() && imagesInitialized) {
						if(startDYE_y.toLowerCase().contains("calculating") || startDYE_b.toLowerCase().contains("calculating") || startDYE_r.toLowerCase().contains("calculating")) {
							
						    r = getStringBounds(startDYE_r, myG);
						    rX = (94 - ((int)Math.round(r.getWidth() / 2)));
						    y = getStringBounds(startDYE_y, myG);
						    yX = (259 - ((int)Math.round(y.getWidth() / 2)));
						    b = getStringBounds(startDYE_b, myG);
						    bX = (418 - ((int)Math.round(b.getWidth() / 2)));
						    
							GrandExchange.Item yellow = GrandExchange.lookup(yellowDYE);
							GrandExchange.Item onion = GrandExchange.lookup(onionID);
							int yFinal = (yellow.getGuidePrice() - (onion.getGuidePrice() * 2)) - 5;
							startDYE_y = "Profit per dye: " + yFinal;

						    r = getStringBounds(startDYE_r, myG);
						    rX = (94 - ((int)Math.round(r.getWidth() / 2)));
						    y = getStringBounds(startDYE_y, myG);
						    yX = (259 - ((int)Math.round(y.getWidth() / 2)));
						    b = getStringBounds(startDYE_b, myG);
						    bX = (418 - ((int)Math.round(b.getWidth() / 2)));
							
							
							GrandExchange.Item blue = GrandExchange.lookup(blueDYE);
							GrandExchange.Item woad = GrandExchange.lookup(woadID);
							int bFinal = (blue.getGuidePrice() - (woad.getGuidePrice() * 2)) - 5;
							startDYE_b = "Profit per dye: " + bFinal;
						    r = getStringBounds(startDYE_r, myG);
						    rX = (94 - ((int)Math.round(r.getWidth() / 2)));
						    y = getStringBounds(startDYE_y, myG);
						    yX = (259 - ((int)Math.round(y.getWidth() / 2)));
						    b = getStringBounds(startDYE_b, myG);
						    bX = (418 - ((int)Math.round(b.getWidth() / 2)));
							
							
							GrandExchange.Item red = GrandExchange.lookup(redDYE);
							GrandExchange.Item redberry = GrandExchange.lookup(redberryID);
							int rFinal = (red.getGuidePrice() - (redberry.getGuidePrice() * 3)) - 5;
							startDYE_r = "Profit per dye: " + rFinal;
						    r = getStringBounds(startDYE_r, myG);
						    rX = (94 - ((int)Math.round(r.getWidth() / 2)));
						    y = getStringBounds(startDYE_y, myG);
						    yX = (259 - ((int)Math.round(y.getWidth() / 2)));
						    b = getStringBounds(startDYE_b, myG);
						    bX = (418 - ((int)Math.round(b.getWidth() / 2)));
							
							
						}
						}
					}
			} catch (Exception e) {
				
			}
			}

		}
		
	}

}
